import {IElement} from "./IElement"
import { XMLSerializer,DOMParser} from 'xmldom'

export class NodeJsElement implements IElement {

    private element:Element
    private static document=new DOMParser().parseFromString('<xml></xml>')
    constructor(element:Element){
        if(!element)
          throw new Error('NodeJsElement constractor: element is null ')
        this.element=element

    }
    getfirstChildNodeValue(): string {
        if(this.element.hasChildNodes()){
            return this.element.firstChild.nodeValue
        }
        return null
    }
    getAttribute(attributeName: string): string {
        let attrValue=this.element.getAttribute(attributeName)
        if(attrValue==='')
           attrValue=null
        return attrValue 
    }
    getElementsByTagName(tagName: string): IElement[] {
        let tagNameHTMLElementList=this.element.getElementsByTagName(tagName);
        let tagNameList:Array<IElement>=[]
        for (let index = 0; index < tagNameHTMLElementList.length; index++) {
            let tempElement=tagNameHTMLElementList.item(index)
            if(tempElement)
              tagNameList.push(new NodeJsElement(tempElement))
        }
        return tagNameList
    }
    getLocalName(): string {
        return this.element.localName
    }
    getNamespaceURI(): string {
        return this.element.namespaceURI
    }
    getElementsByTagNameNS(namespaceURI: string, tagName: string): IElement[] {
        let tagNameHTMLElementList=this.element.getElementsByTagNameNS(namespaceURI,tagName)
        let tagNameList:Array<IElement>=[]
        for (let index = 0; index < tagNameHTMLElementList.item.length; index++) {
            let tempElement=tagNameHTMLElementList.item(index)
            if(tempElement)
              tagNameList.push(new NodeJsElement(tempElement))
        }
        return tagNameList
    }
    setAttribute(attrName: string, attrValue: string): void {
        this.element.setAttribute(attrName,attrValue)
    }

    /**
     * 获取内部的节点
     * @returns 本元素的节点
     */
    protected getElement():Element {
        return this.element
    }
    appendChild(element: IElement): IElement {

        if(element instanceof NodeJsElement){
           this.element.appendChild(element.getElement())
          return this
        }
        throw new Error('element is not instanceof BrowserElement so call appendChild error')
    }
    removeAttribute(attrName: string): IElement {
        this.element.removeAttribute(attrName)
        return this
    }
    hasChildNodes(): boolean {
        return this.element.hasChildNodes()
    }
    getAllChildNodeValue(): string {
        let childValueArray=[]
        for (let index = 0; index < this.element.childNodes.length; index++) {
            let tempElement=this.element.childNodes.item(index)
            if(tempElement.nodeValue)
              childValueArray.push(tempElement.nodeValue)
        }
        if(childValueArray.length>0)
         return childValueArray.join('')
        else
          return ''
    }
    toXmlStr(): string {
        let r = (new XMLSerializer()).serializeToString(this.element);
        return r
    }
    changeOrAddNodeValue(nodeValue: string): void {
      let tNode = NodeJsElement.document.createTextNode(nodeValue)
      if(this.element.firstChild)
       this.element.replaceChild(tNode,this.element.firstChild)
      else
        this.element.appendChild(tNode)
    }
    clone(allchildren: boolean): IElement {
        throw new Error("Method not implemented.");
    }

}